package gwtadmin.client;

import gwtadmin.client.wsdltree.QName;
import gwtadmin.client.wsdltree.Wt;
import gwtadmin.client.wsdltree.WtPolicy;
import gwtadmin.client.wsdltree.WtPortType;
import gwtadmin.client.wsdltree.WtService;

import java.util.List;


import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.Tree;
import com.google.gwt.user.client.ui.TreeItem;
import com.google.gwt.user.client.ui.VerticalPanel;

/////////////////////////////////////////////////////////////////////////////////////////////

class PortTypeProperty extends VerticalPanel implements ClickHandler {
	
	public PortTypeProperty() {
		super();
		
		add(fileName);
		add(info);
		
		fileName.addClickHandler(this);
		
		info.getElement().setAttribute("wrap", "off");
		info.setSize("600px", "400px");
		
		setStyleName("decorFrame");
	}
	
	public void setFileName(String fileName) {
		this.fileName.setText(fileName);
	}
	
	public void setInfo(String info) {
		this.info.setValue(info);
	}
	
	@Override
	public void onClick(ClickEvent event) {
		Window.open(fileName.getText(), "", null);
	}
	
	public Hyperlink fileName = new Hyperlink("", "");
	public TextArea info = new TextArea();
}

/////////////////////////////////////////////////////////////////////////////////////////////

class ServiceProperty extends VerticalPanel implements ClickHandler {
	
	public ServiceProperty() {
		super();
		
		add(fileName);
		add(info);
		
		fileName.addClickHandler(this);
		
		info.getElement().setAttribute("wrap", "off");
		info.setSize("600px", "400px");
		
		setStyleName("decorFrame");
	}
	
	public void setFileName(String fileName) {
		this.fileName.setText(fileName);
	}
	
	public void setInfo(String info) {
		this.info.setValue(info);
	}
	
	@Override
	public void onClick(ClickEvent event) {
		Window.open(fileName.getText(), "", null);
	}
	
	public Hyperlink fileName = new Hyperlink("", "");
	public TextArea info = new TextArea();
}

/////////////////////////////////////////////////////////////////////////////////////////////

class PolicyProperty extends VerticalPanel implements ClickHandler {
	
	public PolicyProperty() {
		super();
		
		add(fileName);
		add(info);
		
		fileName.addClickHandler(this);
		
		info.getElement().setAttribute("wrap", "off");
		info.setSize("600px", "400px");
		
		setStyleName("decorFrame");
	}
	
	public void setFileName(String fileName) {
		this.fileName.setText(fileName);
	}
	
	public void setInfo(String info) {
		this.info.setValue(info);
	}
	
	@Override
	public void onClick(ClickEvent event) {
		Window.open(fileName.getText(), "", null);
	}
	
	public Hyperlink fileName = new Hyperlink("", "");
	public TextArea info = new TextArea();
}

/////////////////////////////////////////////////////////////////////////////////////////////

class ComplexTreeItem extends TreeItem {
	public ComplexTreeItem(QName qname) {
		super(qname.name);
		this.qname = qname;
		
		setTitle(qname.uri);
	}
	
	public ComplexTreeItem(String text, QName qname) {
		super(text);
		
		this.qname = qname;
	}
	
	public ComplexTreeItem(Wt wt) {
		super(wt.qname.name);
		this.qname = wt.qname;
		
		setTitle(wt.qname.uri);
	}
	
	public ComplexTreeItem(String text, Wt wt) {
		super(text);
		
		this.qname = wt.qname;
	}
	
	public QName qname;
}

/////////////////////////////////////////////////////////////////////////////////////////////

public class FormWsdlTree extends VerticalPanel implements
		AsyncCallback<WsdlTreeInfo>,SelectionHandler<TreeItem>,MouseDownHandler {

	private Tree tree = new Tree();

	private HorizontalPanel hp = new HorizontalPanel();
	private VerticalPanel vpRight = new VerticalPanel();
	private PanelSwitcher panelSwitch = null;
	
	private PortTypeProperty propsPortType = new PortTypeProperty();
	private ServiceProperty propsService = new ServiceProperty();
	private PolicyProperty propsPolicy = new PolicyProperty();

	private WsdlTreeInfo treeInfo = null;

	public FormWsdlTree() {
	//	vpRight.setStyleName("undecorFrame");
		
		panelSwitch = new PanelSwitcher(vpRight);
		panelSwitch.addWidget(propsPortType);
		panelSwitch.addWidget(propsService);
		panelSwitch.addWidget(propsPolicy);

		hp.add(tree);
		hp.add(vpRight);
		
		tree.addSelectionHandler(this);
		tree.addStyleName("decorFrame");
		add(hp);
	}
	
	public void showWait(boolean show) {
		tree.clear();
		
		if (show) {
			tree.addItem("Wait for loading tree...");
		}
	}

	@Override
	public void onSuccess(WsdlTreeInfo result) {
		showWait(false);
		treeInfo = result;
		
		for (WtPortType portType : result.portTypes) {
			ComplexTreeItem ctiPortType = new ComplexTreeItem(portType);
			tree.addItem(ctiPortType);
			
			List<WtService> services = result.findServices(portType);
			
			for (WtService svc : services) {
				ComplexTreeItem ctiSvc = new ComplexTreeItem(svc);
				ctiPortType.addItem(ctiSvc);
				
				for (WtPolicy pol : svc.policies) {
					ctiSvc.addItem(new ComplexTreeItem(pol));
				}
			}
		}
	}

	@Override
	public void onFailure(Throwable caught) {
		showWait(false);
		Window.alert("RPC Error");
	}

	@Override
	public void onSelection(SelectionEvent<TreeItem> event) {
		if (treeInfo == null)
			return;

		ComplexTreeItem item = (ComplexTreeItem) event.getSelectedItem();
		ComplexTreeItem parent = (ComplexTreeItem) event.getSelectedItem().getParentItem();
		
		if (parent == null) {
			WtPortType portType = treeInfo.getPortType(item.qname);
			propsPortType.setFileName(portType.url);
			propsPortType.setInfo(portType + "");
			panelSwitch.SwitchTo(propsPortType);
		} else if (parent.getParentItem() == null) {
			WtService svc = treeInfo.getService(item.qname);
			propsService.setFileName(svc.url);
			propsService.setInfo(svc + "");
			panelSwitch.SwitchTo(propsService);
		} else if (parent.getParentItem().getParentItem() == null) {
			WtPolicy pol = treeInfo.getPolicy(item.qname);
			propsPolicy.setFileName(pol.url);
			propsPolicy.setInfo(pol + "");
			panelSwitch.SwitchTo(propsPolicy);
		} else {
			panelSwitch.SwitchTo(null);
		}
	}

	@Override
	public void onMouseDown(MouseDownEvent event) {
		
	}
}
